home *** CD-ROM | disk | FTP | other *** search
/ The Programmer Disk / The Programmer Disk (Microforum).iso / xpro / extra / pro13 / cc.c < prev    next >
C/C++ Source or Header  |  1993-08-28  |  12KB  |  614 lines

  1. /*
  2.     cc.C
  3.  
  4.     Version 1.5
  5.  
  6.     Clock Calendar
  7.  
  8.     Copyright (C) 1993, Geoff Friesen B.Sc.
  9.     All rights reserved.
  10.  
  11.     Developed with: Borland C++ 3.1
  12. */
  13.  
  14. /*
  15.     set ti=c:\borlandc\tsr\tsrlib
  16.     t cc -hc -x
  17.  
  18.     The BIOS memory location 0040:0084 is set to the number of
  19.     screen rows less one.  For example, if the screen has been
  20.     set to 25 lines then the value 24 would be stored here.  A
  21.     value of 49 would be stored if 50-line mode were in effect
  22.     (on VGA adaptors).  This address is used by recent adaptor
  23.     BIOSes.  Older BIOSes do not use it.  Therefore, assume it
  24.     to be valid if it returns a 24, 42, or 49.  The 42 is used
  25.     in EGA 43-line mode.
  26. */
  27.  
  28. #if !defined(__TINY__)
  29. #error Tiny Memory Model Expected
  30. #endif
  31.  
  32. #include "tsrlib.H"
  33.  
  34. char *title = "\r\n"
  35.  
  36. "╔═════════════════════════════════════════╗\r\n"
  37. "║  ▒▒▒   ▒▒▒                              ║\r\n"
  38. "║ ▒   ▒ ▒   ▒                             ║\r\n"
  39. "║ ▒     ▒                                 ║\r\n"
  40. "║ ▒     ▒     Version 1.5                 ║\r\n"
  41. "║ ▒     ▒                                 ║\r\n"
  42. "║ ▒   ▒ ▒   ▒                             ║\r\n"
  43. "║  ▒▒▒   ▒▒▒                              ║\r\n"
  44. "║                                         ║\r\n"
  45. "║ Copyright (C) 1993, Geoff Friesen B.Sc. ║\r\n"
  46. "║ All rights reserved.                    ║\r\n"
  47. "╚═════════════════════════════════════════╝\r\n"
  48. "$";
  49.  
  50. int bw [] =
  51. {
  52.    WHITE,                               /* clock */
  53.    (LIGHTGRAY << 4) | BLACK,            /* calendar back */
  54.    WHITE,                               /* month */
  55.    WHITE,                               /* year */
  56.    WHITE                                /* current day */
  57. };
  58.  
  59. int color [] =
  60. {
  61.    LIGHTGREEN,                          /* clock */
  62.    (CYAN << 4) | BLACK,                 /* calendar back */
  63.    LIGHTMAGENTA,                        /* month */
  64.    LIGHTGREEN,                          /* year */
  65.    YELLOW                               /* current day */
  66. };
  67.  
  68. #define NATTR   (sizeof(bw)/sizeof(bw [0]))
  69.  
  70. int attr [NATTR];
  71.  
  72. char clock_template [] = " 00:00:00  M ";
  73.  
  74. char *cal_template [] =
  75. {
  76.      "╔═════════════════════════════════════════╗",
  77.      "║                                         ║",
  78.      "║                                         ║",
  79.      "║ SUN   MON   TUE   WED   THU   FRI   SAT ║",
  80.      "╠═════╤═════╤═════╤═════╤═════╤═════╤═════╣",
  81.      "║     │     │     │     │     │     │     ║",
  82.      "╟─────┼─────┼─────┼─────┼─────┼─────┼─────╢",
  83.      "║     │     │     │     │     │     │     ║",
  84.      "╟─────┼─────┼─────┼─────┼─────┼─────┼─────╢",
  85.      "║     │     │     │     │     │     │     ║",
  86.      "╟─────┼─────┼─────┼─────┼─────┼─────┼─────╢",
  87.      "║     │     │     │     │     │     │     ║",
  88.      "╟─────┼─────┼─────┼─────┼─────┼─────┼─────╢",
  89.      "║     │     │     │     │     │     │     ║",
  90.      "╟─────┼─────┼─────┼─────┴─────┴─────┴─────╢",
  91.      "║     │     │     │                       ║",
  92.      "╚═════╧═════╧═════╧═══════════════════════╝"
  93. };
  94.  
  95. #define NCOLS   43
  96. #define NROWS   17
  97.  
  98. char buffer [(NCOLS+1)*(NROWS+1)*2];
  99.  
  100. int column = (80-NCOLS)/2;
  101. int row;
  102. int srow = -1;                /* suggested row */
  103. int oldyear = 0;
  104. int oldmonth = 0;
  105. int oldday = 0;
  106.  
  107. char *months [] =
  108. {
  109.    "January",
  110.    "February",
  111.    "March",
  112.    "April",
  113.    "May",
  114.    "June",
  115.    "July",
  116.    "August",
  117.    "September",
  118.    "October",
  119.    "November",
  120.    "December"
  121. };
  122.  
  123. int days [] =
  124. {
  125.    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  126. };
  127.  
  128. void    draw_cal        (struct date *d);
  129. void    draw_clock      (struct time *t);
  130. int     fday            (int year, int month);
  131. void    write_day       (int year, int month, int day);
  132. void    write_month     (int month);
  133. void    write_year      (int year);
  134.  
  135. void    mclosectx    (char *buffer);
  136. void    mhide        (void);
  137. int    mlbpressed    (void);
  138. int    mopenctx    (char *buffer, int maxsize);
  139. int    mrange        (int x1, int y1, int x2, int y2);
  140. void    mshow        (void);
  141.  
  142. void main (void)
  143. {
  144.    struct date d;
  145.    struct time t;
  146.    static char mbuffer [1000];
  147.    int cshape, hidden = 0, i, mexist, nrows, vmode, x, y;
  148.  
  149.    if ((vmode = v_getmode ()) != BW80 && vmode != C80 && vmode != MONO)
  150.        return;
  151.  
  152.    nrows = peekb(0x40, 0x84)+1;
  153.    if (nrows != 25 && nrows != 43 && nrows != 50)
  154.        nrows = 25;
  155.  
  156.    row = (srow == -1 || srow+NROWS > nrows) ? (nrows-NROWS) >> 1 : srow;
  157.  
  158.    for (i = 0; i < NATTR; i++)
  159.     attr [i] = (vmode == C80) ? color [i] : bw [i];
  160.  
  161.    cshape = v_getshape ();
  162.    v_setshape (0x2000);         /* hide cursor */
  163.  
  164.    x = v_wherex ();
  165.    y = v_wherey ();
  166.  
  167.    v_screen (SCREEN_SAVE, column, row, NCOLS+1, NROWS+1, buffer);
  168.  
  169.    mexist = mopenctx (mbuffer, 1000);
  170.  
  171.    if (mexist)
  172.        mshow ();
  173.  
  174.    while (1)
  175.    {
  176.       if (mexist && mrange (column, row, column+NCOLS, row+NROWS))
  177.       {
  178.       mhide ();
  179.       hidden = 1;
  180.       }
  181.  
  182.       getdate (&d);
  183.       draw_cal (&d);
  184.  
  185.       gettime (&t);
  186.       draw_clock (&t);
  187.  
  188.       if (mexist && hidden)
  189.       {
  190.       mshow ();
  191.       hidden = 0;
  192.       }
  193.  
  194.       if (mexist && mlbpressed ())
  195.       break;
  196.  
  197.       if (k_iskey ())
  198.       {
  199.       (void) k_fetch ();
  200.       break;
  201.       }
  202.    }
  203.  
  204.    if (mexist)
  205.    {
  206.        mhide ();
  207.        mclosectx (mbuffer);
  208.    }
  209.  
  210.    v_screen (SCREEN_RESTORE, column, row, NCOLS+1, NROWS+1, buffer);
  211.    v_gotoxy (x, y);
  212.    v_setshape (cshape);
  213.  
  214.    oldyear = oldmonth = oldday = 0;
  215. }
  216.  
  217. void draw_cal (struct date *d)
  218. {
  219.    int i;
  220.  
  221.    if (d->da_year == oldyear && d->da_mon == oldmonth
  222.        && d->da_day == oldday)
  223.        return;
  224.  
  225.    v_setattr (attr [1]);
  226.  
  227.    for (i = 0; i < NROWS; i++)
  228.    {
  229.     v_gotoxy (column, row+i);
  230.     v_cputs (cal_template [i]);
  231.    }
  232.  
  233.    v_shadow (column, row, NCOLS, NROWS);
  234.  
  235.    write_year (d->da_year);
  236.    write_month (d->da_mon);
  237.    write_day (d->da_year, d->da_mon, d->da_day);
  238.  
  239.    oldyear = d->da_year;
  240.    oldmonth = d->da_mon;
  241.    oldday = d->da_day;
  242. }
  243.  
  244. void draw_clock (struct time *t)
  245. {
  246.    clock_template [10] = (t->ti_hour < 12) ? 'A' : 'P';
  247.  
  248.    if (!t->ti_hour)
  249.        t->ti_hour = 12;
  250.    else
  251.        if (t->ti_hour > 12)
  252.        t->ti_hour -=12;
  253.  
  254.    clock_template [1] = t->ti_hour / 10 + ((t->ti_hour < 10) ? ' ' : '0');
  255.    clock_template [2] = t->ti_hour % 10 + '0';
  256.  
  257.    clock_template [4] = t->ti_min / 10 + '0';
  258.    clock_template [5] = t->ti_min % 10 + '0';
  259.  
  260.    clock_template [7] = t->ti_sec / 10 + '0';
  261.    clock_template [8] = t->ti_sec % 10 + '0';
  262.  
  263.    v_setattr (attr [0]);
  264.    v_gotoxy (column+NCOLS-19, row+NROWS-2);
  265.    v_cputs (clock_template);
  266. }
  267.  
  268. int fday (int year, int month)
  269. {
  270.    int i, d = 0;
  271.  
  272.    for (i = 1583; i < year; i++)
  273.    {
  274.     if (isleap (i))
  275.         d += 366;
  276.     else
  277.         d += 365;
  278.  
  279.     d %= 7;
  280.    }
  281.  
  282.    for (i = 1; i < month; i++)
  283.    {
  284.     d += days [i-1];
  285.     if (i == 2 && isleap (year))
  286.         d++;
  287.  
  288.     d %= 7;
  289.    }
  290.  
  291.    if (!d)
  292.        d = 7;
  293.  
  294.    return (d-1);
  295. }
  296.  
  297. void write_day (int year, int month, int day)
  298. {
  299.    int c, d, nd, r;
  300.    char buffer [3];
  301.  
  302.    c = fday (year, month) * 6 + 3;
  303.    r = 5;
  304.  
  305.    nd = days [month-1];
  306.    if (month == 2 && isleap (year))
  307.        nd++;
  308.  
  309.    v_setattr (attr [1]);
  310.  
  311.    buffer [2] = '\0';
  312.  
  313.    for (d = 1; d <= nd; d++)
  314.    {
  315.     buffer [0] = d / 10 +  ((d < 10) ? ' ' : '0');
  316.     buffer [1] = d % 10 + '0';
  317.  
  318.     v_gotoxy (column+c, row+r);
  319.     if (d == day)
  320.     {
  321.         v_setattr (attr [4]);
  322.         v_cputs (buffer);
  323.         v_setattr (attr [1]);
  324.     }
  325.     else
  326.         v_cputs (buffer);
  327.  
  328.     if ((c += 6) > 39)
  329.     {
  330.         c = 3;
  331.         r += 2;
  332.     }
  333.    }
  334. }
  335.  
  336. void write_month (int month)
  337. {
  338.    v_gotoxy (column+((NCOLS-strlen (months [--month])) >> 1), row+1);
  339.    v_setattr (attr [2]);
  340.    v_cputs (months [month]);
  341. }
  342.  
  343. void write_year (int year)
  344. {
  345.    char buffer [5];
  346.  
  347.    (void) _itoa (year, buffer);
  348.    v_setattr (attr [3]);
  349.    v_gotoxy (column+2, row+1);
  350.    v_cputs (buffer);
  351.    v_gotoxy (column+NCOLS-6, row+1);
  352.    v_cputs (buffer);
  353. }
  354.  
  355. /*
  356.     mclosectx
  357.  
  358.     Close the mouse context.  Restore the mouse driver to its
  359.     original settings.
  360. */
  361.  
  362. void mclosectx (char *buffer)
  363. {
  364.    _ES = FP_SEG(buffer);
  365.    _DX = FP_OFF(buffer);
  366.    _AX = 0x17;
  367.    geninterrupt(0x33);
  368. }
  369.  
  370. /*
  371.     mhide
  372.  
  373.     Hide the mouse cursor.
  374. */
  375.  
  376. void mhide (void)
  377. {
  378.    _AX = 2;
  379.    geninterrupt(0x33);
  380. }
  381.  
  382. /*
  383.     mlbpressed
  384.  
  385.     Return the pressed/released status of the leftmost mouse button.
  386.     A nonzero return value indicates that the button is pressed.
  387. */
  388.  
  389. int mlbpressed (void)
  390. {
  391.    _AX = 3;
  392.    geninterrupt(0x33);
  393.  
  394.    return (_BX & 1);
  395. }
  396.  
  397. /*
  398.     mopenctx
  399.  
  400.     Open the mouse context.  The current driver settings are saved
  401.     to the buffer argument.  The mouse driver is then reset.  Zero
  402.     is returned if there is no installed driver or the buffer size
  403.     required to hold the driver settings exceeds the maximum size
  404.     passed to this function.
  405. */
  406.  
  407. int mopenctx (char *buffer, int maxsize)
  408. {
  409.    _AX = 0x15;
  410.    geninterrupt(0x33);
  411.  
  412.    if (!_BX || _BX > maxsize)
  413.        return 0;
  414.  
  415.    _ES = FP_SEG(buffer);
  416.    _DX = FP_OFF(buffer);
  417.    _AX = 0x16;
  418.    geninterrupt(0x33);
  419.  
  420.    _AX = 0;
  421.    geninterrupt(0x33);
  422.  
  423.    return (!_AX) ? 0 : 1;
  424. }
  425.  
  426. /*
  427.     mrange
  428.  
  429.     Determine if mouse cursor lies within a specific rectangle.
  430.     Return nonzero if it does.
  431. */
  432.  
  433. int mrange (int x1, int y1, int x2, int y2)
  434. {
  435.    unsigned x, y;
  436.  
  437.    _AX = 3;
  438.    geninterrupt(0x33);
  439.  
  440.    x = _CX;
  441.    y = _DX;
  442.  
  443.    x >>= 3;    /* Convert pixel coordinates to character coordinates. */
  444.    y >>= 3;
  445.  
  446.    x++;
  447.    y++;        /* Make coordinates relative to (1, 1). */
  448.  
  449.    return (x >= x1 && x <= x2 && y >= y1 && y <= y2);
  450. }
  451.  
  452. /*
  453.     mshow
  454.  
  455.     Show the mouse cursor.
  456. */
  457.  
  458. void mshow (void)
  459. {
  460.    _AX = 1;
  461.    geninterrupt(0x33);
  462. }
  463.  
  464. #ifndef INCL_GETDATE
  465. #include "getdate.C"
  466. #endif
  467.  
  468. #ifndef    INCL_GETTIME
  469. #include "gettime.C"
  470. #endif
  471.  
  472. #ifndef INCL_ISDIGIT
  473. #include "isdigit.C"
  474. #endif
  475.  
  476. #ifndef INCL_ISLEAP
  477. #include "isleap.C"
  478. #endif
  479.  
  480. #ifndef INCL_ITOA
  481. #include "itoa.C"
  482. #endif
  483.  
  484. #ifndef INCL_KFETCH
  485. #include "kfetch.C"
  486. #endif
  487.  
  488. #ifndef INCL_KISKEY
  489. #include "kiskey.C"
  490. #endif
  491.  
  492. #ifndef INCL_VCPUTS
  493. #include "vcputs.C"
  494. #endif
  495.  
  496. #ifndef INCL_VGETMODE
  497. #include "vgetmode.C"
  498. #endif
  499.  
  500. #ifndef INCL_VGETSHAPE
  501. #include "vgetshap.C"
  502. #endif
  503.  
  504. #ifndef INCL_VGOTOXY
  505. #include "vgotoxy.C"
  506. #endif
  507.  
  508. #ifndef INCL_VSCROLL
  509. #include "vscroll.C"
  510. #endif
  511.  
  512. #ifndef INCL_VSETATTR
  513. #include "vsetattr.C"
  514. #endif
  515.  
  516. #ifndef INCL_VSETSHAPE
  517. #include "vsetshap.C"
  518. #endif
  519.  
  520. #ifndef INCL_VSHADOW
  521. #include "vshadow.C"
  522. #endif
  523.  
  524. #ifndef INCL_VWHEREX
  525. #include "vwherex.C"
  526. #endif
  527.  
  528. #ifndef INCL_VWHEREY
  529. #include "vwherey.C"
  530. #endif
  531.  
  532. int xparse (int option)
  533. {
  534.    int accum, digit;
  535.  
  536.    if (option == 'R')    /* RESET OPTION */
  537.    {
  538.        setrseg ();
  539.        column = (80-NCOLS)/2;
  540.        srow = -1;
  541.        setcseg ();
  542.        return 0;
  543.    }
  544.  
  545.    if (option == 'X')    /* COLUMN OPTION */
  546.    {
  547.        if (!isdigit ((digit = parse ())))
  548.        {
  549.        _AH = 9;
  550.        _DX = FP_OFF("cc: digit expected after 'X'\r\n$");
  551.        geninterrupt(0x21);
  552.        return -1;
  553.        }
  554.  
  555.        accum = digit-'0';
  556.  
  557.        if (!isdigit ((digit = parse ())))
  558.        unparse ();
  559.        else
  560.        {
  561.        accum *= 10;
  562.        accum += (digit-'0');
  563.        }
  564.  
  565.        if (accum < 1 || accum > (80-NCOLS))
  566.        {
  567.        _AH = 9;
  568.        _DX = FP_OFF("cc: column out of range ...\r\n$");
  569.        geninterrupt(0x21);
  570.        return -1;
  571.        }
  572.  
  573.        setrseg ();
  574.        column = accum;
  575.        setcseg ();
  576.        return 0;
  577.    }
  578.  
  579.    if (option == 'Y')    /* ROW OPTION */
  580.    {
  581.        if (!isdigit ((digit = parse ())))
  582.        {
  583.        _AH = 9;
  584.        _DX = FP_OFF("cc: digit expected after 'Y'\r\n$");
  585.        geninterrupt(0x21);
  586.        return -1;
  587.        }
  588.  
  589.        accum = digit-'0';
  590.  
  591.        if (!isdigit ((digit = parse ())))
  592.        unparse ();
  593.        else
  594.        {
  595.        accum *= 10;
  596.        accum += (digit-'0');
  597.        }
  598.  
  599.        if (accum < 1 || accum > (50-NROWS))
  600.        {
  601.        _AH = 9;
  602.        _DX = FP_OFF("cc: row out of range ...\r\n$");
  603.        geninterrupt(0x21);
  604.        return -1;
  605.        }
  606.  
  607.        setrseg ();
  608.        srow = accum;
  609.        setcseg ();
  610.        return 0;
  611.    }
  612.  
  613.    return -1;
  614. }